#! /usr/bin/env bash

# Copyright (c) 2006-2015, Universities Space Research Association (USRA).
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the Universities Space Research Association nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY USRA ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL USRA BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#Validate file
valid()
{
  if [ ! -e $1 ] && [ $quiet = 1 ]
    then
      echo "WARNING: $1 does not exist"
  fi
  return
}

warn()
{
   if [ $quiet = 1 ]
     then
       echo "$1"
   fi
}

usage="Usage: plexilsim -p <plan> [-script <script>]+ [-q] [-v [-h <hostname>] [-n <portnumber>] [-b]] [-d <debug file>] \
                     [-ch] [-l <library>]* [-L <library dir>]*\n Use -help for more options"
help="Options:\n\
\n\
 -p | -plan <plan> \n\
\t	load plan (required) \n\
\t	specify PLEXIL plan (required) \n\
 -s | -script <scrpt>+ \n\
\t	specify simulation script (required) \n\
 -q | -quiet \n\
\t 	suppresses a leading printed summary and default debug messages.\n\
 -v | -viewer \n\
\t 	requests that plan state be transmitted to the Plexil viewer.\n\
 -h | -hostname <name> \n\
\t 	hostname of viewer\n\
 -n | -port <number> \n\
\t 	portnumber of viewer\n\
 -b | -blocking \n\
\t 	enables breakpoints in viewer (recommended)\n\
 -d | -debug <file name> \n\
\t 	debug file (default is Debug.cfg)\n\
 -ch | -check \n\
\t 	runs the PLEXIL static checker prior to executing plan\n\
 -l | -library <file name>\n\
\t 	specifies a plan library (.plx file)\n\
 -L | -libraryPath <directory name>\n\
\t 	specifies a directory for finding plan library files\n\
 -? | -help \n\
\t	displays this message"
# -a used only for viewer acquire PID

if [ -z "$PLEXIL_HOME" ]
then
    echo Error: Please set environment variable PLEXIL_HOME
    echo to the full pathname of your 'plexil' or 'trunk' directory.
    echo Exiting.
    exit 1
fi

. $PLEXIL_HOME/scripts/plexil-setup.sh

#separate command-line from run-ue output
echo

platform=`uname`
quiet=1 #quiet default
plan_nm="" #plan name
plan_cmd="" #plan command
script="" #script
config_nm="${PLEXIL_HOME}/src/apps/StandAloneSimulator/PlexilSimulator/test/config.xml"
config_cmd="-c ${config_nm}"
script="" #command script name
libraries="" #library files
library_dirs="" #library directories
debug_file="" #debug file
check="false" #run static checker

if [ ! $1 ]
  then
  echo -e $usage
  exit 1
fi

for i in $*
do
    case $1 in 	
        -q | -quiet ) quiet=0;;	
	-p | -plan ) shift
	plan_nm="$1"
	plan_cmd="-p $1";;
	-s | -script ) shift
	valid $1
	script="$script $1";;
	-c | -config ) shift
	valid $1
	config_nm="$1"
	config_cmd="-c $1";;
	-s | -script ) shift
	valid $1
	script="$1";;
	-l | -library ) shift
	valid $1
	libraries="$libraries -l $1";;
	-L | -libraryPath ) shift
	valid $1	
	library_dirs="$library_dirs -L $1";;
	-d | -debug ) shift
	valid $1
	debug_file="-d $1";;
	-v | -viewer ) viewer="-v";;	#viewer listener enabled	
	-h | -hostname ) shift
	host_in="-h $1";;	#viewer host name
	-n | -port ) shift
	port_in="-n $1"
	skip=1;;	#viewer port
	-b | -blocking ) block="-b";;	#enable viewer break point	
	-k | -check ) check="true";;	
	-a ) automate="true";;
	-help ) echo -e $help
	  exit 2;;
	-? ) echo 'Error: missing argument for option' $1
	  echo -e $usage
	  exit 2;; 
    esac
    shift
done

# Check the plan's existence
if [ "$plan_nm" = "" ] 
  then
    warn "Error: No plan defined"
    exit 1
fi    

# Check if user typed invalid plan
if [ ! -e "$plan_nm" ]
  then
        echo Error: Plan $plan_nm, does not exist.
        exit 1    
fi

# Redefine current path config to look for dummy config on current path
if [ ! -e "$script_nm" ] || [ "$script_nm" = "" ]
   then
        if [ ! -e "$current_config" ] ; then
	  current_config=$default_config_name
	fi
fi

# Check plan for errors
if [ "$check" = "true" ] && [ -f $PLEXIL_HOME/scripts/checkPlexil ]
  then 
       echo "Checking Plan..."
       $PLEXIL_HOME/scripts/checkPlexil $plan_nm
       if [ ! -e "$plan_nm" ] && [ $? -gt 0 ]
         then
	   echo Error: $plan_nm, contains runtime error
           exit 1
	fi
    elif [ ! -f $PLEXIL_HOME/scripts/checkPlexil ]
      then
	echo Error: $PLEXIL_HOME/scripts/checkPlexil not found.	
	exit 1
fi  

# Print summary if desired
if [ $quiet -eq 1 ] 
  then
    echo Running executive from $PLEXIL_HOME
    echo "  Plan:              $plan_nm"
    echo "  Scripts:    	$script"
#    echo "  Telemetry:         $tele_scr"
    echo "  Libraries:         $libraries"
    echo "  Library directories: $library_dirs"
    echo
fi
xterm -e ipc &
`xterm -e run-sas $script` &
sas_kill=$!
trap "{ kill $sas_kill; }" SIGINT
trap "{ kill $sas_kill; }" SIGQUIT
sleep 2

if [ "$automate" = "true" ]
  then    
    plexilexec -a $plan_cmd $config_cmd $debug_file $viewer $host_in $port_in $block $library_dirs $libraries &    
    trap "{ kill $!; }" SIGINT
    trap "{ kill $!; }" SIGQUIT    
  else     
    plexilexec $plan_cmd $config_cmd $debug_file $viewer $host_in $port_in $block $library_dirs $libraries
fi
trap "{ killall ipc; }" EXIT
trap "{ killall central; }" EXIT
